#include "block_queue.h"
#include "task.h"

class thread_data
{
    friend void *product(void *argv);
    friend void *consum(void *argv);

public:
    thread_data(block_queue<task> *bq, string name)
        : _bq(bq), _name(name)
    {
    }

private:
    block_queue<task> *_bq;
    string _name;
};

void *product(void *argv)
{

    thread_data *d = static_cast<thread_data *>(argv);
    while (1)
    {
        int x = rand() % 100;
        usleep(100); // 防止两个数字太接近
        int y = rand() % 100;
        char op = opers[rand() % opers.size()];
        task t(x, y, op);
        d->_bq->push(t); // 传任务
        cout << d->_name << "->";
        t.proc_print();
        sleep(1);
    }
}

void *consum(void *argv)
{
    thread_data *d = static_cast<thread_data *>(argv);
    while (1)
    {
        task t;
        d->_bq->pop(&t); // 接收任务
        // t.run();//处理任务
        t(); // 仿函数的方式来处理任务
        cout << d->_name << "->";
        t.consu_print();
    }
}

int main()
{
    srand((unsigned int)time(nullptr)); // 生成随机数种子（状态是全局的）
    pthread_t tid_1, tid_2, tid_3, tid_4, tid_5;
    block_queue<task> *bq = new block_queue<task>(5);
    thread_data d1(bq, "tid_1");
    thread_data d2(bq, "tid_2");
    thread_data d3(bq, "tid_3");
    thread_data d4(bq, "tid_4");
    thread_data d5(bq, "tid_5");

    pthread_create(&tid_1, nullptr, product, (void *)&d1);
    pthread_create(&tid_2, nullptr, product, (void *)&d2);
    pthread_create(&tid_3, nullptr, product, (void *)&d3);

    pthread_create(&tid_4, nullptr, consum, (void *)&d4);
    pthread_create(&tid_5, nullptr, consum, (void *)&d5);

    pthread_join(tid_1, nullptr);
    pthread_join(tid_2, nullptr);

    return 0;
}